package com.fanxuankai.boot.log.autoconfigure;

import com.fanxuankai.boot.log.LogDetailService;
import com.fanxuankai.boot.log.enums.StoreType;
import com.fanxuankai.boot.log.store.JdbcLogStore;
import com.fanxuankai.boot.log.store.LogStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.*;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
import ru.yandex.clickhouse.ClickHouseDataSource;

/**
 * @author fanxuankai
 */
@Conditional(ClickHouseLogStoreAutoConfiguration.ClickHouseCondition.class)
@ConditionalOnClass({ClickHouseDataSource.class})
@EnableConfigurationProperties({ClickHouseProperties.class})
@ConditionalOnProperty(name = LogProperties.ENABLED, matchIfMissing = true)
public class ClickHouseLogStoreAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public LogStore logStore(LogProperties logProperties, @Autowired(required = false) ClickHouseDataSource dataSource,
                             ClickHouseProperties properties, LogDetailService logDetailService) {
        return new JdbcLogStore(dataSource == null
                ? new ClickHouseDataSource(properties.getUrl(), properties) : dataSource, logProperties, logDetailService);
    }

    protected static class ClickHouseCondition extends SpringBootCondition {
        @Override
        public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
            ConditionMessage.Builder message = ConditionMessage.forCondition("Log Store ClickHouse Condition");
            Environment environment = context.getEnvironment();
            String keyValue = environment.getProperty(LogProperties.STORE_TYPE);
            if (StoreType.CLICKHOUSE.name().equalsIgnoreCase(keyValue)) {
                return ConditionOutcome.match(message.foundExactly("provided private or symmetric key"));
            }
            return ConditionOutcome.noMatch(message.didNotFind("provided private or symmetric key").atAll());
        }
    }
}